package codepulse.blogmoon.cn.system.service.impl;


import codepulse.blogmoon.cn.common.utils.BaseConvert;
import codepulse.blogmoon.cn.system.dto.admin.SysAdminMenuTreeDTO;
import codepulse.blogmoon.cn.system.entity.SysAdminRole;
import codepulse.blogmoon.cn.system.entity.SysAdminRoleMenuRel;
import codepulse.blogmoon.cn.system.enums.MenuTypeEnum;
import codepulse.blogmoon.cn.system.enums.RoleTypeEnum;
import codepulse.blogmoon.cn.system.service.SysAdminRoleMenuRelService;
import codepulse.blogmoon.cn.system.service.SysAdminRoleService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import codepulse.blogmoon.cn.system.entity.SysAdminMenu;
import codepulse.blogmoon.cn.system.service.SysAdminMenuService;
import codepulse.blogmoon.cn.system.mapper.SysAdminMenuMapper;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.assertj.core.util.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author 61748
 * @description 针对表【sys_admin_menu(系统-菜单表)】的数据库操作Service实现
 * @createDate 2024-01-15 14:27:05
 */
@Service
public class SysAdminMenuServiceImpl extends ServiceImpl<SysAdminMenuMapper, SysAdminMenu>
        implements SysAdminMenuService {


    @Resource
    private SysAdminRoleService sysAdminRoleService;

    @Resource
    private SysAdminRoleMenuRelService sysAdminRoleMenuRelService;


    @Override
    public List<SysAdminMenuTreeDTO> getTree(Long bizAcctId) {

        List<SysAdminMenu> menus = baseMapper.selectMenuByBizAcctId(bizAcctId);
        if (isAdmin(bizAcctId)) {
            menus = list();
        }
        return convertTree(menus);
    }

    @Override
    public List<SysAdminMenuTreeDTO> allMenu() {
        List<SysAdminMenu> menus = list();
        return convertTree(menus);
    }

    @Override
    public void insertOrUpdate(SysAdminMenuTreeDTO dto) {
        SysAdminMenu sysAdminMenu = BaseConvert.convert(dto, SysAdminMenu.class);
        if (Objects.equals(sysAdminMenu.getType(), MenuTypeEnum.MENU_GROUP.getCode())) {
            sysAdminMenu.setComponent("Layout");
        }
        if (dto.getId() == null) {
            sysAdminMenu.setCreateField();
            baseMapper.insert(sysAdminMenu);
        } else {
            sysAdminMenu.setModifyField();
            baseMapper.updateById(sysAdminMenu);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeMenu(Long id) {
        sysAdminRoleMenuRelService.remove(Wrappers.<SysAdminRoleMenuRel>lambdaQuery()
                .eq(SysAdminRoleMenuRel::getMenuId, id));
        removeById(id);
    }

    private List<SysAdminMenuTreeDTO> convertTree(List<SysAdminMenu> menus) {
        if (CollectionUtils.isEmpty(menus)) {
            return Lists.newArrayList();
        }
        List<SysAdminMenuTreeDTO> rootList = Lists.newArrayList();
        Map<Long, SysAdminMenuTreeDTO> menuTreeMap = menus.stream().collect(Collectors.toMap(SysAdminMenu::getId,
                item -> BaseConvert.convert(item, SysAdminMenuTreeDTO.class)));
        for (SysAdminMenuTreeDTO adminMenuTreeDTO : menuTreeMap.values()) {
            if (Objects.isNull(adminMenuTreeDTO.getParentId()) || Objects.equals(0L, adminMenuTreeDTO.getParentId())) {
                rootList.add(adminMenuTreeDTO);
                continue;
            }
            SysAdminMenuTreeDTO sysAdminMenuTreeDTO = menuTreeMap.get(adminMenuTreeDTO.getParentId());
            if (Objects.isNull(sysAdminMenuTreeDTO)) {
                rootList.add(adminMenuTreeDTO);
                continue;
            }
            if (Objects.isNull(sysAdminMenuTreeDTO.getChildren())) {
                sysAdminMenuTreeDTO.setChildren(Lists.newArrayList());
            }
            sysAdminMenuTreeDTO.getChildren().add(adminMenuTreeDTO);
            sysAdminMenuTreeDTO.getChildren().sort(Comparator.comparing(SysAdminMenuTreeDTO::getSort));
        }
        rootList.sort(Comparator.comparing(SysAdminMenuTreeDTO::getSort));
        return rootList;
    }


    private boolean isAdmin(Long bizAcctId) {
        List<SysAdminRole> adminRoleList = sysAdminRoleService.getRoleByAcctId(bizAcctId);
        if (CollectionUtils.isEmpty(adminRoleList)) {
            return false;
        }
        return adminRoleList.stream().anyMatch(item ->
                Objects.equals(RoleTypeEnum.ADMIN.getCode(), item.getRoleType()));

    }
}




